<template>
    <div class="approval flex-1 pl-4 overflow-auto">
        <div class="approval-header mb-4">
            <h2 class="text-lg font-bold">审批流程</h2>
        </div>

        <div class="approval-status mb-4" v-if="state.approvalFlag">
            <a-alert message="当前状态：待审批" type="info" show-icon />
            <a-alert message="当前状态：已审批" type="success" show-icon />
        </div>

        <div class="approval-timeline">
            <a-timeline>
                <template v-if="state.nodeUsers.length == 0">
                    <div class="empty-prediction-node">
                        <div class="empty-icon-container">
                            <svg xmlns="http://www.w3.org/2000/svg" class="empty-icon" viewBox="0 0 24 24" fill="none"
                                stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
                                <polygon
                                    points="12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2">
                                </polygon>
                            </svg>
                        </div>
                        <div class="empty-text">暂无预测节点数据</div>
                        <div class="empty-description">预测节点将根据后端返回数据自动渲染</div>
                        <div class="empty-hint">请确保流程配置正确且后端服务正常</div>
                    </div>
                </template>
                <template v-else>
                    <a-timeline-item color="blue" v-for="node in state.nodeUsers" :key="node.nodeId">
                        <div class="timeline-title font-medium">{{ node.nodeName }}</div>
                        <div class="timeline-content text-gray-500">
                            <template v-if="node.prop == 'start'">
                                <div>申请人：{{ node.userName }}</div>
                            </template>
                            <template v-else-if="node.prop == 'approval'">
                                <div>审批人：{{ node.userName }}</div>
                                <div>状态：等待审批</div>
                            </template>
                            <template v-else-if="node.prop == 'copy'">
                                <div>抄送人：{{ node.userName }}</div>
                                <div>状态：等待抄送</div>
                            </template>
                            <template v-else-if="node.prop == 'condition'">
                                <div>条件处理</div>
                            </template>
                        </div>
                    </a-timeline-item>
                </template>
            </a-timeline>
        </div>

        <div class="approval-info mt-6 bg-gray-50 p-4 rounded">
            <h3 class="font-medium mb-2">流程信息</h3>
            <div class="info-item flex mb-2">
                <span class="info-label w-24 text-gray-500">表单类型：</span>
                <span>{{ basucFormData?.formName }}申请</span>
            </div>
            <div class="info-item flex mb-2">
                <span class="info-label w-24 text-gray-500">流程编号：</span>
                <span>{{ basucFormData?.flowId }}</span>
            </div>
        </div>
    </div>
</template>

<script setup lang="ts">
import { apiFlowForcast } from '@/api/flow/flow';
import { computed, reactive, watch } from 'vue';
import { useUserInfo } from '@/stores/userInfo';
import type { ResType } from '@/api/types';
import loading2 from '@/components/loading/loading2.vue';
import type { BaseWidgetType } from '@/xyFDesigner/type';
import { apiGetCurLoginUserDirectorInfo, apiGetCurOrgParent } from '@/api/sys/sysOrg';

const userInfoStore = useUserInfo()

const props = withDefaults(
    defineProps<{
        flowContent: any,
        basucFormData: any, //表单配置
        formState: any, //表单填写数据
        widgets: BaseWidgetType[]
    }>(),
    {
        formData: {},
        flowContent: {}
    }
)

const state = reactive({
    approvalFlag: false,
    nodeUsers: [] as any[], //渲染流程节点
    loading: false
})

const getNodeUserName = async(node: any) => {
    const properties = node.properties
    if (properties.prop == "approval") {
        if (properties.approvalType == 1) {
            return "自动通过"
        }
        if (properties.approvalType == 2) {
            let name = ""
            if (properties.assigneeType == 1) {
                name += userInfoStore.state.userInfos.realName
                if (properties.flowNodeSelfAuditorType == 1) {
                    name += "（自审）"
                } else if (properties.flowNodeSelfAuditorType == 2) {
                    name += "（自动通过）"
                } else if (properties.flowNodeSelfAuditorType == 3) {
                    const directorInfoRes :ResType<any>= await apiGetCurLoginUserDirectorInfo(userInfoStore.state.userInfos.orgId)
                    name = directorInfoRes.data.result.realName
                }
            } else if (properties.assigneeType == 2) {
                let layer = properties.layer 
                if(layer == 0){
                    const directorInfoRes :ResType<any>= await apiGetCurLoginUserDirectorInfo(userInfoStore.state.userInfos.orgId)
                    name = directorInfoRes.data.result.realName
                }else {
                    let orgID = userInfoStore.state.userInfos.orgId
                    let originOrgId = orgID
                    let isFindAllParOrg = true 
                    for (let i = 1; i <= layer; i++) {
                        let parOrgRes:ResType<any> = await apiGetCurOrgParent(orgID)
                        if(parOrgRes.data.result == null){
                            isFindAllParOrg = false
                            break
                        }
                        orgID = parOrgRes.data.result.id
                    }
                    let resultOrgId = isFindAllParOrg ? orgID : originOrgId
                    const directorInfoRes :ResType<any>= await apiGetCurLoginUserDirectorInfo(resultOrgId)
                    name = directorInfoRes.data.result.realName
                }
            } else if (properties.assigneeType == 3) {
                const assignees = properties.assignees
                for (let i = 0; i < assignees.length; i++) {
                    name+=assignees[i].realName
                    if(i < assignees.length - 1){
                        name+="、"
                    }
                }
                if(assignees.length >= 2){
                    switch(properties.multiInstanceApprovalType){
                        case 1:
                            name+="会签(所有审批人同意))"
                            break;
                        case 2:
                            name+="(或签(一名审批人同意))"
                            break;
                        case 3:
                            name+="(依次审批(顺序审批人同意))"
                            break;
                    }
                }
            }

            if(!properties.assigneeType){
                if(properties.flowNodeNoAuditorType == 1){
                    name += "自动通过"
                }else if(properties.flowNodeNoAuditorType == 2){
                    const assignees = properties.assignees
                    for (let i = 0; i < assignees.length; i++) {
                        name+=assignees[i].realName
                        if(i < assignees.length - 1){
                            name+="、"
                        }
                    }
                    if(assignees.length >= 2){
                        switch(properties.multiInstanceApprovalType){
                            case 1:
                                name+="会签(所有审批人同意))"
                                break;
                            case 2:
                                name+="(或签(一名审批人同意))"
                                break;
                            case 3:
                                name+="(依次审批(顺序审批人同意))"
                                break;
                        }
                    }
                }
            }
            return name
        }
    } else if (properties.prop == "copy") {
        let name =""
        const ccs = properties.ccs
        for (let i = 0; i < ccs.length; i++) {
            const c = ccs[i];
            name += c.realName
            if(i < ccs.length - 1){
                name+="、"
            }
        }
        return name
    }
}

/**
 * 
 * @param nodeId 初始化从开始节点递归查询
 * @param nodes 
 * @param edges 
 * @param nodeUserList 
 */
const getNodeUsers = async(node: any, nodes: any[], edges: any[], nodeUserList: any[]) => {
    if (["approval", "copy"].includes(node.properties.prop)) {
        nodeUserList.push({
            prop: node.properties.prop,
            nodeId: node.id,
            nodeName: node.properties.name,
            userName: await getNodeUserName(node)
        })
    } else if (node.properties.prop == "start") {
        nodeUserList.push({
            prop: node.properties.prop,
            nodeId: node.id,
            nodeName: "发起申请",
            userName: userInfoStore.state.userInfos.account
        })
    }

    if (node.properties.prop == "end") {
        nodeUserList.push({
            prop: node.properties.prop,
            nodeId: node.id,
            nodeName: "流程结束",
            userName: ""
        })
        return nodeUserList
    } else {
        let nextIds = edges.filter((e: any) => e.sourceNodeId == node.id).map((e: any) => e.targetNodeId)
        if (nextIds.length > 1) {
            // 条件节点
            const allConditionNodes = nodes.filter((n: any) => nextIds.includes(n.id)).sort((a: any, b: any) => {
                return a.properties.priorityLevel - b.properties.priorityLevel
            })
            // 查询条件中符合的分支
            const form = props.formState
            const nextConditionBranch = allConditionNodes.filter((n: any) => {
                let flag = true
                const conditions: any[] = n.properties.conditions
                if (!conditions || n.properties.defaultCondition) {
                    return true
                }
                const res = conditions.map((cond: any) => {
                    const val = cond.val
                    // 条件发起人处理
                    if (cond.varName == "userId") {
                        if (cond.operator == 6) {
                            let found = false
                            for (let j = 0; j < val.length; j++) {
                                const v = val[j]
                                
                                if (v.type == "user") {
                                    if (v.id == userInfoStore.state.userInfos.id) {
                                        found = true
                                        break
                                    }
                                } else if (v.type == "dept") {
                                    if (v.id == userInfoStore.state.userInfos.orgId) {
                                        found = true
                                        break
                                    }
                                }
                            }
                            if (found == false) {
                                return false
                            }else {
                                return true
                            }
                        }
                        if (cond.operator == 7) {
                            let found = false
                            for (let j = 0; j < val.length; j++) {
                                const v = val[j]
                                if (v.type == "user") {
                                    if (v.id == userInfoStore.state.userInfos.id) {
                                        found = true
                                        break
                                    }
                                } else if (v.type == "dept") {
                                    if (v.id == userInfoStore.state.userInfos.orgId) {
                                        found = true
                                        break
                                    }
                                }
                            }
                            if (found == true) {
                                return false
                            }else {
                                return true
                            }
                        }
                    }
                })
                
                if(res.some(i=>i == false)){
                    return false
                }else{
                    return true
                }
            })
            //默认分支必定添加进去，当所有条件都不符合的时候取默认分支
            return getNodeUsers(nextConditionBranch[0],nodes,edges,nodeUserList)

        } else {
            const firstNodeId = nextIds[0]
            const node = nodes.find((n: any) => n.id == firstNodeId)
            return getNodeUsers(node, nodes, edges, nodeUserList)
        }
    }


    // state.loading = true
    // const res = await apiFlowForcast({
    //     flowId:props.basucFormData?.flowId,
    //     createUserId:userInfoStore.state.userInfos.id,
    //     form:JSON.stringify(props.formState)
    // }) as ResType<any>
    // state.nodeUsers = res.data.result

    // // 排序节点
    // sortNodes()
    // state.loading = false

}

const sortNodes = () => {
    let { edges, nodes }: { edges: any[], nodes: any[] } = props.flowContent

    let startNode = nodes.find((n: any) => n.properties.prop == 'start')
    let res: any[] = []
    function mapRes(startNodeId: any) {
        edges.forEach(e => {
            let sourceId = e.sourceNodeId
            let targetId = e.targetNodeId
            if (sourceId == startNodeId) {
                const index = state.nodeUsers.findIndex((n: any) => n.nodeId == sourceId)
                if (index != -1) {
                    res.push(state.nodeUsers[index])
                    mapRes(targetId)
                }
            }
        })
    }
    mapRes(startNode.id)
    console.log(res);

    state.nodeUsers = res
}

// 处理预测前准备
const beginGetNodeUsers = async() => {
    const nodes: any[] = props.flowContent.nodes || []
    const edges: any[] = props.flowContent.edges || []
    const startNode = nodes.find((n: any) => n.properties.prop == 'start')
    if (!startNode) {
        return
    }
    const res: any[] = []
    const nodeUsers =await getNodeUsers(startNode, nodes, edges, res)
    console.log(nodeUsers);
    state.nodeUsers = nodeUsers
}

watch(
    () => props.formState,
    () => {
        // 收集必填列表
        let requiredRes = props.widgets.filter((item) => {
            return item.options.required
        })
        // 判断必填列表是否都已经填写内容
        let requiredFlag = true
        requiredRes.some(item => {
            let key = item?.options.name
            let val = props.formState[key!]
            if (!val) {
                requiredFlag = false
                return
            }
        })
        if (requiredFlag) {
            beginGetNodeUsers()
        }
    },
    {
        deep: true
    }
)
</script>

<style lang="scss" scoped>
.approval {
    height: 100%;
    overflow-y: auto;
    padding: 16px;

    &::-webkit-scrollbar {
        width: 6px;
        background: transparent;
    }

    &::-webkit-scrollbar-thumb {
        background-color: #a19e9e;
        border-radius: 4px;

        &:hover {
            background-color: #ccc;
        }
    }
}

.timeline-title {
    font-size: 14px;
}

.timeline-content {
    font-size: 12px;
    margin-top: 4px;
}

.empty-prediction-node {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    padding: 40px 20px;
    background-color: #fafafa;
    border-radius: 8px;
    border: 1px dashed #e8e8e8;
    text-align: center;
}

.empty-icon-container {
    width: 64px;
    height: 64px;
    display: flex;
    align-items: center;
    justify-content: center;
    margin-bottom: 16px;
    background-color: #f0f2f5;
    border-radius: 50%;
}

.empty-icon {
    width: 32px;
    height: 32px;
    color: #919191;
}

.empty-text {
    font-size: 16px;
    font-weight: 500;
    color: #333;
    margin-bottom: 8px;
}

.empty-description {
    font-size: 14px;
    color: #999;
    margin-bottom: 4px;
    max-width: 240px;
}

.empty-hint {
    font-size: 12px;
    color: #c0c0c0;
    max-width: 240px;
}
</style>
